﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace LightSwitchApplication
{
    /// <summary>
    /// https://github.com/SignalR/SignalR/wiki/Hubs
    /// </summary>
    [HubName("placeHub")]
    public class PlaceHub : Hub
    {
        #region fields
        private static Dictionary<string,string> _groupConnections = new Dictionary<string,string>();

        private enum GroupActions
        {
            Add,
            Remove
        }
        #endregion

        #region props
        #endregion

        #region ~costr
        public PlaceHub()
        {
        }
        public PlaceHub(int PlaceId)
        {
            Join(PlaceId.ToString());
        }
        #endregion

        #region methods

        public void SendToGroup(string groupName, string message)
        {
            //call method on everyone but the caller
            //Clients.OthersInGroup("place " + groupName).addMessage(message);
            //call method on everyone in group excluding the specified connection ids
            string[] excludeIds = new string[] {  };
            try
            {
                Clients.Group("place " + groupName, excludeIds).addMessage(message);
            }
            catch (Exception ex)
            {

            }
        }

        public void Join(string groupName)
        {
            if (Context != null && Context.ConnectionId != null)
            {
                Groups.Add(Context.ConnectionId, "place " + groupName);
                UpdateConnectionsCache("place " + groupName, GroupActions.Add);
            }
        }

        public void Disconnect(string groupName)
        {
            if (Context != null && Context.ConnectionId != null)
            {
                Groups.Remove(Context.ConnectionId, "place " + groupName);
                UpdateConnectionsCache("place " + groupName, GroupActions.Remove);
            }
        }

        public int GetGroupConectionsCount(string groupName)
        {
            int result = 0;
            if (_groupConnections.ContainsKey(groupName))
            {
                result = _groupConnections[groupName].Split(';').Length-1;
            }
            return result;
        }

        private void UpdateConnectionsCache(string groupName, GroupActions action)
        {
            if (!_groupConnections.ContainsKey(groupName))
            {
                _groupConnections[groupName] = string.Empty;
            }
            if (action == GroupActions.Add && !_groupConnections[groupName].Contains(Context.ConnectionId + ";"))
            {
                _groupConnections[groupName] = _groupConnections[groupName] + Context.ConnectionId + ";";
            }
            else if (action == GroupActions.Remove && _groupConnections[groupName].Contains(Context.ConnectionId + ";"))
            {
                _groupConnections[groupName] = _groupConnections[groupName].Replace(Context.ConnectionId + ";", "");
            }
            Clients.Group(groupName, new string[] { }).addMessage(string.Format("{0} active user(s)", GetGroupConectionsCount(groupName)));
        }

        #endregion

        #region events
        public override Task OnConnected()
        {
            //Join("places"); 
            //Clients.All.joined(Context.ConnectionId, DateTime.Now.ToString());
            return base.OnConnected();
        }

        public override Task OnDisconnected()
        {
            //_connectionsCount--;
            //return Clients.All.leave(Context.ConnectionId, DateTime.Now.ToString());
            return base.OnDisconnected();
        }

        public override Task OnReconnected()
        {
            //return Clients.All.rejoined(Context.ConnectionId, DateTime.Now.ToString());
            return base.OnReconnected();
        }
        #endregion
    }
}